package com.grm.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.grm.common.Result;
import com.grm.sys.entity.SysMenu;
import com.grm.sys.entity.SysRoleMenu;
import com.grm.sys.service.SysMenuService;
import com.grm.sys.service.SysRoleMenuService;
import com.grm.sys.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 系统菜单控制器
 *
 * @author gaorimao
 * @date 2022/06/24
 */
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController {
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysRoleService sysRoleService;

    @PreAuthorize("hasAuthority('sys:menu:add')")
    @PostMapping("/insert")
    public Result insert(@RequestBody SysMenu sysMenu) {
        QueryWrapper<SysMenu> sysMenuQueryWrapper = new QueryWrapper<>();
        sysMenuQueryWrapper.eq("label", sysMenu.getLabel());
        SysMenu dbSysMenu = sysMenuService.getOne(sysMenuQueryWrapper);
        if (dbSysMenu != null) {
            return Result.failed(500, "菜单已存在，不能重复添加！");
        }
        sysMenu.setCreated(new Date());
        sysMenuService.save(sysMenu);
        return Result.success("查询所有菜单成功！", sysMenu);
    }

    @PreAuthorize("hasAuthority('sys:menu:update')")
    @PutMapping("/update")
    public Result update(@RequestBody SysMenu sysMenu) {
        sysMenu.setUpdated(new Date());
        sysMenuService.updateById(sysMenu);
        return Result.success("更新菜单成功！", sysMenu);
    }

    @Transactional(rollbackFor = Exception.class)
    @PreAuthorize("hasAuthority('sys:menu:delete')")
    @DeleteMapping("/delete/{menuId}")
    public Result delete(@PathVariable Long menuId) {
        // 查询此菜单下有没有子菜单
        QueryWrapper<SysMenu> menuQueryWrapper = new QueryWrapper<>();
        menuQueryWrapper.eq("parent_id",menuId);
        List<SysMenu> children = sysMenuService.list(menuQueryWrapper);
        if(!ObjectUtils.isEmpty(children)){
            return Result.failed(500,"存在子菜单，不能删除！");
        }
        // 删除菜单
        sysMenuService.removeById(menuId);
        // 删除角色菜单关联关系
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_id", menuId);
        sysRoleMenuService.remove(queryWrapper);
        return Result.success("删除菜单成功！");
    }

    @PreAuthorize("hasAuthority('sys:menu:list')")
    @GetMapping("/query/all/tree")
    public Result list() {
        List<SysMenu> sysMenus = sysMenuService.list();
        List<SysMenu> trees = sysMenuService.buildTree(sysMenus);
        return Result.success("查询权限树结构成功！", trees);
    }

    @PreAuthorize("hasAuthority('sys:menu:getCatalogueAndMenuTree')")
    @GetMapping("/query/catalogueAndMenu/tree")
    public Result getCatalogueAndMenuTreeAll() {
        QueryWrapper<SysMenu> sysMenuQueryWrapper = new QueryWrapper<>();
        sysMenuQueryWrapper.in("type", 0, 1);
        List<SysMenu> sysMenus = sysMenuService.list(sysMenuQueryWrapper);
        List<SysMenu> trees = sysMenuService.buildTree(sysMenus);
        return Result.success("查询目录&菜单树结构成功！", trees);
    }

    @PreAuthorize("hasAuthority('sys:menu:getMenuIdsByRoleId')")
    @GetMapping("/getMenuIds/{roleId}")
    public Result getMenuIdsByRoleId(@PathVariable Long roleId) {
        QueryWrapper<SysRoleMenu> sysRoleMenuQueryWrapper = new QueryWrapper<>();
        sysRoleMenuQueryWrapper.eq("role_id", roleId);
        List<SysRoleMenu> list = sysRoleMenuService.list(sysRoleMenuQueryWrapper);
        List<Long> menuIds = Optional.ofNullable(list).orElse(new ArrayList<>())
                .stream().map(SysRoleMenu::getMenuId).distinct().collect(Collectors.toList());
        return Result.success("查询角色关联的menuIds成功", menuIds);
    }
}
